# -*- coding: utf-8 -*-

'''
This file is a template Textobot plugin implementation.

You can use this file as the new plugin's startup code.

API Reference: 

https://gitee.com/geekneo/Textobot/blob/master/Doc/api.md


If you have any advises, We are happy to hear from you.


Follow us:
----------------------------------------------------------------------
        Email                           971159199@qq.com
        公众号                           刘柏江
        百家号                           刘柏江VM

        微博                             刘柏江VM
        头条                             刘柏江VM
        码云                             https://gitee.com/geekneo/
----------------------------------------------------------------------


Version history:

2019.12.25 {
        * add idle event
}

2019.12.14 {
        * add template plugin code running inside frida
}

2019.12.07 {
        * initialize template plugin code
}
'''

import os
import codecs
import urllib2
import time
import subprocess
import json
import frida

# TODO: change to your target bundleID
target_bid = 'com.apple.Preferences'

# it's only for VSCode Textobot-Run command
# TODO:
# turn to 0 before you pack this plugin
# turn to 1 if you want to run directly from VSCode
dev_mode = 0

if not dev_mode:
    # this plugin package's root directory
    pkg_root = os.path.dirname(__file__)

    # pickup this plugin's version dynamically
    with open(pkg_root + '/textobot.json', 'r') as fp:
        pkginfo = json.load(fp)
        pkg_version = pkginfo['version']

# frida device
idev = frida.get_remote_device()

# dump event information
def dump_event(dictarg):
    print('####################')
    for pt in dictarg.keys():
        text = dictarg[pt]
        print('%s len=%d, str=%s' % (pt, len(text), text))
    return {}

# input text demonstration
def input_text(pt, text):
    TB_touch_pair(pt)
    time.sleep(3)
    TB_input_text(text)
    time.sleep(3)

# run an app
def run_app(bid):
    print('start app : %s' % (bid))
    TB_launch(bid)

# run a shell command
def run_cmd(s):
    print('run cmd : %s' % (s))
    subprocess.Popen(s, shell=True).wait()

# url request for get/post
def url_request(url, body = None):
    req = urllib2.Request(url)
    req.add_header('User-Agent', 'textobot')
    if body:
        fp = urllib2.urlopen(req, data=body.encode('utf-8'))
    else:
        fp = urllib2.urlopen(req)
    result = fp.read().decode('utf-8')
    fp.close()
    return result

# handler for text views
def proc_event_views(pts, texts):
    # TODO: add your implementation for UI texts event
    pass

# handler for dialog
def proc_event_dialog(pts, texts):
    # TODO: add your implementation for Dialog texts event
    pass

# handler for frida message event
def on_frida_message(message, data):
    # TODO: add your implementation for your javascript message event
    print(message)

# fire javascript to target app
def fire_javascript(bid, pid):
    # let apple's Preferences app be our textobotee
    if bid == target_bid:
        # attach to target
        session = idev.attach(int(pid))
        if not session:
            print("Oops, what's wrong with attaching for %s %s." % (bid, pid))
            return

        # pickup this plugin's javascript code dynamically
        with codecs.open(pkg_root + '/textobot.js', 'r', 'utf-8') as fp:
            jscode = fp.read()
            # create script session
            script = session.create_script(jscode)
            # fire to run the javascript code
            script.on('message', on_frida_message)
            script.load()

# handler for event
def TB_on_event(dictarg):
    #dump_event(dictarg)

    target = dictarg['target']
    event = dictarg['event']
    if event == 'texts':
        proc_event_views(dictarg.keys(), dictarg.values())
    elif event == 'dlgtexts':
        proc_event_dialog(dictarg.keys(), dictarg.values())
    return {}

# handler for main
def TB_main(dictarg):
    #dump_event(dictarg)

    # TODO: add your implementation for plugin event
    event = dictarg['event']
    if event == 'install':
        print('install Template textobot plugin')
    elif event == 'uninstall':
        print('uninstall Template textobot plugin')
    elif event == 'start':
        print('start Template textobot plugin')
    elif event == 'stop':
        print('stop Template textobot plugin')
    elif event == 'enable':
        print('enable Template textobot plugin')
    elif event == 'disable':
        print('disable Template textobot plugin')
    elif event == 'apprun':
        print(dictarg['name'] + ' is running')
        fire_javascript(dictarg['name'], dictarg['pid'])
    elif event == 'appdie':
        print(dictarg['name'] + ' has been died')
    elif event == 'idle':
        print('idle event received')
    else:
        print('what to do with : %s' % (event))
    return {}

# it's only for VSCode Textobot-Run command, can only recv TB_on_event
if dev_mode:
    # only available in dev mode
    TB_event_callback = TB_on_event
    TB_clear_log()
    print('The textobot template plugin(dev) is waiting for event ...')
# running in release plugin mode, can recv TB_on_event & TB_main
else:
    print('The textobot template plugin(%s) is waiting for event ...' % (pkg_version))
